// 首先Vue2当中通过observer对数据状态（data）进行数据变化的观察，一旦数据发生变化，会进行消息的发布来通知更改数据对应的订阅者。
// Vue2会对模块进行解析，在解析的过程序当中会对与数据产生绑定的DOM进行newWatch生成订阅者处理，并将订阅者对与其数据产生绑定。一旦数据变化，对应的订阅者会对DOM进行对应的操作。

function Vue(config) {
    const {el,data={},methods={}} = config;
    this.$data = data;
    this.$binds = {};
    for(let key in methods){
        this[key] = methods[key];
    }
    this.observe();

    this.$el = el;
    if(typeof el === "string"){
        this.$el = document.querySelector(el);
    }

    this.compile();
    this.$mount(el);

}

Object.assign(Vue.prototype,{
    observe(){
        for(let key in this.$data){
            this.$binds[key] = [];
            Object.defineProperty(this,key,{
                get(){
                    return this.$data[key];
                },
                set(v){
                    this.$data[key] = v;
                    //发布
                    this.$binds[key].forEach(watcher=>watcher.update(v))
                }
            })
        }
    },
    compile(){
        for(let i=0;i<this.$el.children.length;i++){
            const node = this.$el.children[i];
            this.compile(node);
            if(node.hasAttribute("v-model")){
                const value = node.getAttribute("v-model");
                node.addEventListener("input",(e)=>{
                    this[value] = e.target.value;
                })
                node.value = this[value];
                //订阅
                this.$binds[value].push(new Watcher(node,'value'))
            }
            if(node.hasAttribute("v-html")){
                const value = node.getAttribute("v-html");
                node.innerHTML = this[value];
                //订阅
                this.$binds[value].push(new Watcher(node,'innerHTML'))
            }
            if(node.hasAttribute("v-text")){
                const value = node.getAttribute("v-text");
                node.innerText = this[value];
                //订阅
                this.$binds[value].push(new Watcher(node,'innerText'))
            }
        }
    },
    $mount(el){
        this.$el = el;
        if(typeof el === "string"){
            this.$el = document.querySelector(el);
        }
        if(this.$el){
            this.compile(this.$el);
        }
    },
})
//创建订阅者
function Watcher(node,prop){
    this.node = node;
    this.prop = prop;
}
Watcher.prototype.update = function (v){
    this.node[this.prop] = v;
}
export default Vue;